package com.example.dps;

import java.util.Arrays;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import com.downpayment.dps.R;

public class LinkExistingAccountActivity extends Activity {

	final static int numSteps = 1;
	int stepNumber = 0;

	final static String tag = "LinkExistingAccount";

	final static int SETUP_USERNAME_STEP = 1;
	final static int ADD_BANK_INFO_STEP = 0;
	final static int MFA_STEP = 2;

	public String[] registerAccountInfo = new String[4];

	public String[] bankInfo = new String[3];

	public WebHelper webHelper;
	public AccountDBHelper accountDBHelper;
	public DBHelper dbHelper;

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
	}

	@Override
	public void onBackPressed() {
		stepNumber--;

		if (stepNumber < 0)
			LinkExistingAccountActivity.this.finish();
		else {
			changeToStepLayout();
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.setup_account_layout);

		this.webHelper = new WebHelper(this);
		this.accountDBHelper = new AccountDBHelper(this);
		this.dbHelper = new DBHelper(this);

		/** if already has a user name, jump to the next section **/
		if (this.dbHelper.getUsername() == null
				|| this.dbHelper.getUsername().equals("")) {
			// this.stepNumber = SETUP_USERNAME_STEP;
		} else {
			/** username created, jump to bank info step **/
			this.stepNumber = ADD_BANK_INFO_STEP;

		}

		Drawable background = Utility.returnAdjustedBackgroundDrawable(this);

		LinearLayout root = (LinearLayout) findViewById(R.id.root);

		root.setBackgroundDrawable(background);

		changeToStepLayout();

	}

	@Override
	public Dialog onCreateDialog(int id) {

		AlertDialog.Builder builder = null;
		LayoutInflater inflater = null;

		switch (id) {
		case Constants.LOGIN_DIALOG:
			builder = new AlertDialog.Builder(this);
			// Get the layout inflater
			inflater = this.getLayoutInflater();

			// Inflate and set the layout for the dialog
			// Pass null as the parent view because its going in the dialog
			// layout
			builder.setView(inflater.inflate(R.layout.login_layout, null))
					// Add action buttons
					.setPositiveButton("Login",
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int id) {

									EditText usernameText = (EditText) ((AlertDialog) dialog)
											.findViewById(R.id.loginUsernameValue);
									EditText passwordText = (EditText) ((AlertDialog) dialog)
											.findViewById(R.id.loginPasswordValue);

									if (usernameText != null
											&& passwordText != null) {
										String username = usernameText
												.getText().toString();
										String password = passwordText
												.getText().toString();

										LinkExistingAccountActivity.this.webHelper
												.login(username, password, true);
									} else {
										Toast.makeText(
												LinkExistingAccountActivity.this,
												"Please enter your username and password",
												Toast.LENGTH_LONG).show();
									}

								}
							})
					.setNegativeButton("Cancel",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {

								}
							});
			return builder.create();

		default:

			String[] banks = new String[this.webHelper.bankMap.size()];
			banks = (String[]) (this.webHelper.bankMap.keySet().toArray(banks));
			Arrays.sort(banks);
			builder = new AlertDialog.Builder(this);
			builder.setTitle("Select Bank:").setItems(banks,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							String[] banks = new String[LinkExistingAccountActivity.this.webHelper.bankMap
									.size()];
							banks = (String[]) (LinkExistingAccountActivity.this.webHelper.bankMap
									.keySet().toArray(banks));
							Arrays.sort(banks);
							String bank = banks[which];

							EditText bankText = (EditText) findViewById(R.id.bankValue);
							bankText.setText(bank);

							bankInfo[0] = String
									.valueOf(LinkExistingAccountActivity.this.webHelper.bankMap
											.get(bank));

						}
					});
			return builder.create();
		}
	}

	protected void changeToStepLayout() {

		LinearLayout mainContentLayout = (LinearLayout) findViewById(R.id.setupAccountMainContent);

		LayoutInflater inflater = LinkExistingAccountActivity.this
				.getLayoutInflater();

		mainContentLayout.removeAllViews();

		int resource = -1;

		TableRow acceptLayout = (TableRow) findViewById(R.id.acceptLayout);
		acceptLayout.setVisibility(View.GONE);

		if (stepNumber == this.SETUP_USERNAME_STEP) {

			resource = R.layout.setup_account_username_layout;

		}

		else if (stepNumber == this.ADD_BANK_INFO_STEP) {

			resource = R.layout.add_bank_credentials_layout;
		}
		
		/** if done all steps, jump to view savings **/
		else if (stepNumber >= this.numSteps) {

			String bank = bankInfo[0];
			String bankName = bankInfo[1];
			String bankPass = bankInfo[2];

			/** if user already has an account, this info will be blank **/
			Log.e("", "calling update existing account");

			LinkExistingAccountActivity.this.webHelper
					.updateExistingAccountInfo(bank, bankName, bankPass, true);

			return;
		}
		
		ScrollView sv = (ScrollView) findViewById(R.id.setupAccountScrollView);
		
		sv.fullScroll(ScrollView.FOCUS_UP);

		mainContentLayout.addView(inflater.inflate(resource, mainContentLayout,
				false));

		updateProgressBar();

		addButtonListeners();

		restoreFormInfo();

	}

	private void restoreFormInfo() {

	}

	private void addButtonListeners() {

		// add bank selector dialog
		if (this.stepNumber == ADD_BANK_INFO_STEP) {
			EditText bankLayout = (EditText) findViewById(R.id.bankValue);

			bankLayout.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View arg0) {
					showDialog(1);

				}

			});
		}
		/** step 1 button listeners **/

		if (stepNumber == SETUP_USERNAME_STEP) {

			TextView existingAccountText = (TextView) findViewById(R.id.existingAccountText);

			existingAccountText.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View view) {
					showDialog(Constants.LOGIN_DIALOG);

				}

			});

		}

		ImageView continueButton = (ImageView) findViewById(R.id.setupContinueBtn);

		continueButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				/** save information **/
				LinkExistingAccountActivity.this.saveFormInfo();

				if (checkFormInfoComplete()){
					/** go to next step **/

					Log.e("", "clicked Continue");
					if (LinkExistingAccountActivity.this.stepNumber == SETUP_USERNAME_STEP) {

						Log.e("", "stepNum = SETUP_USERNAME");

						String username = registerAccountInfo[0];
						String email = registerAccountInfo[1];
						String password = registerAccountInfo[2];

						if (checkFormInfoComplete()) {
							LinkExistingAccountActivity.this.webHelper
									.registerYodleeUser(username, password,
											email);
						}

					}

					else if (LinkExistingAccountActivity.this.stepNumber >= LinkExistingAccountActivity.this.numSteps) {
						
						String bank = bankInfo[0];
						String bankName = bankInfo[1];
						String bankPass = bankInfo[2];

						String username = registerAccountInfo[0];
						String email = registerAccountInfo[1];
						String password = registerAccountInfo[2];

						/** if user needs to register, register account **/
						if (registerAccountInfo[0] != null) {
							LinkExistingAccountActivity.this.webHelper
									.addExistingAccountInfo(bank, bankName,
											bankPass, true);
						}
						/**
						 * if user already has an account, this info will be
						 * blank
						 **/
						else {
							LinkExistingAccountActivity.this.webHelper
									.updateExistingAccountInfo(bank, bankName,
											bankPass, true);
						}

						LinkExistingAccountActivity.this.dbHelper
								.setMode(DBHelper.EXISTING_ACCOUNT_MODE);

					}

					/** change layout accordingly **/
					else {


						/** if account is already setup, skip registration step **/
						if (LinkExistingAccountActivity.this.dbHelper
								.getUsername() != null) {
							LinkExistingAccountActivity.this.stepNumber += 2;
						}
						/** else go to next (registration step) **/
						else {
							LinkExistingAccountActivity.this.stepNumber = LinkExistingAccountActivity.this.SETUP_USERNAME_STEP;
						}

						LinkExistingAccountActivity.this.changeToStepLayout();

					}
				}

			}
		});

		continueButton.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {

				ImageView view = (ImageView) v;

				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					view.setImageDrawable(view.getResources().getDrawable(
							R.drawable.continue_btn_clicked));
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					view.setImageDrawable(view.getResources().getDrawable(
							R.drawable.continue_btn));
				} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
					view.setImageDrawable(view.getResources().getDrawable(
							R.drawable.continue_btn));
				}

				return false;
			}

		});

		ImageView backButton = (ImageView) findViewById(R.id.setupAccountBackButton);
		backButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				stepNumber--;

				if (stepNumber < 0)
					LinkExistingAccountActivity.this.finish();
				else {
					changeToStepLayout();
				}

			}

		});
	}

	public void updateProgressBar() {

		TextView stepText = (TextView) findViewById(R.id.stepText);
		stepText.setText("Step " + (stepNumber + 1) + " of " + (numSteps + 1));

		ProgressBar progressBar = (ProgressBar) findViewById(R.id.setupAccountProgress);
		progressBar.setMax(numSteps + 1);

		progressBar.setProgress(stepNumber + 1);
	}

	public boolean checkFormInfoComplete() {

		/** check if register username form completed **/
		if (stepNumber == SETUP_USERNAME_STEP) {

			/** check info is complete **/
			for (int i = 0; i < registerAccountInfo.length; i++) {

				if (registerAccountInfo[i] == null
						|| registerAccountInfo[i].equals("")) {
					Toast.makeText(this,
							"Please complete the form before continuing.",
							Toast.LENGTH_LONG).show();
					Toast.makeText(this,
							"Please complete the form before continuing.",
							Toast.LENGTH_LONG).show();
					return false;
				}

			}

			if (this.webHelper.hasConnection() == false) {
				Toast.makeText(this, "No internet connection available",
						Toast.LENGTH_LONG).show();
				Toast.makeText(this, "No internet connection available",
						Toast.LENGTH_LONG).show();
				return false;
			}

			/** check that username is not taken **/
			String username = registerAccountInfo[0];
			if (this.webHelper.checkUsernameAvailable(username) == false) {
				Toast.makeText(this, "Username is not available",
						Toast.LENGTH_LONG).show();
				Toast.makeText(this, "Username is not available",
						Toast.LENGTH_LONG).show();
				return false;
			}

			/** check that passwords match **/
			String password = registerAccountInfo[2];
			String confirmPassword = registerAccountInfo[3];
			if (password != null && confirmPassword != null
					&& !password.equals(confirmPassword)) {

				Toast.makeText(this, "Passwords do not match!",
						Toast.LENGTH_LONG).show();
				Toast.makeText(this, "Passwords do not match!",
						Toast.LENGTH_LONG).show();

				return false;
			}

			if (!Utility.validPassword(password)) {
				Toast.makeText(
						this,
						"Passwords must contain an Upper case letter, a digit, and be atleast 8 characters",
						Toast.LENGTH_LONG).show();
				Toast.makeText(
						this,
						"Passwords must contain an Upper case letter, a digit, and be atleast 8 characters",
						Toast.LENGTH_LONG).show();
				return false;
			}

			String email = registerAccountInfo[1];
			if (!Utility.validEmail(email)) {
				Toast.makeText(this, "Invalid Email", Toast.LENGTH_LONG).show();
				Toast.makeText(this, "Invalid Email", Toast.LENGTH_LONG).show();
				return false;
			}

			if (this.webHelper.hasConnection() == false) {
				Toast.makeText(this, "No internet connection available",
						Toast.LENGTH_LONG).show();
				Toast.makeText(this, "No internet connection available",
						Toast.LENGTH_LONG).show();
				return false;
			}

			/** check that username is not taken **/
			username = registerAccountInfo[0];
			if (this.webHelper.checkUsernameAvailable(username) == false) {
				Toast.makeText(this, "Username is not available",
						Toast.LENGTH_LONG).show();
				Toast.makeText(this, "Username is not available",
						Toast.LENGTH_LONG).show();
				return false;
			}

		}

		if (stepNumber == ADD_BANK_INFO_STEP) {

			// check login info

			// check for MFA

		}

		return true;

	}

	public void onGetExistingAccountInfo(Account account) {
		// the given account contains the amount in the users bank account.

		// set the DPS account amount to this account.amount;

		if (account.amount >= 0 && account.name != null) {
			if (this.accountDBHelper.hasDPSAccount()) {
				this.accountDBHelper.deleteAll();
				this.accountDBHelper.addYodleeDPSAccount(account);
			} else {
				// create the DPS account
				this.accountDBHelper.addYodleeDPSAccount(account);

			}

			// account has been created!
			this.dbHelper.setBoolean(DBHelper.COLUMN_ACCOUNT_CREATED, 1);

			// uses yodlee = true!
			this.dbHelper.setBoolean(DBHelper.COLUMN_USES_YODLEE, 1);

			this.dbHelper.setColumnString(DBHelper.COLUMN_BANK_USERNAME,
					bankInfo[1]);
			this.dbHelper.setColumnString(DBHelper.COLUMN_BANK_PASSWORD,
					bankInfo[2]);

			this.dbHelper.setColumnString(DBHelper.COLUMN_USERNAME,
					registerAccountInfo[0]);
			this.dbHelper.setColumnString(DBHelper.COLUMN_PASSWORD,
					registerAccountInfo[2]);

			Intent intent = new Intent(LinkExistingAccountActivity.this,
					TabRoot.class);
			intent.putExtra("START_TAB", "view_savings");
			this.startActivity(intent);
			this.finish();

		}

	}

	public void onRegisterYodleeUser(boolean result) {

		this.dbHelper.setMode(DBHelper.EXISTING_ACCOUNT_MODE);
		
		
		String bank = bankInfo[0];
		String bankName = bankInfo[1];
		String bankPass = bankInfo[2];
		
		LinkExistingAccountActivity.this.webHelper.addExistingAccountInfo(bank, bankName, bankPass, true);
		

	}

	public void saveFormInfo() {

		if (stepNumber == SETUP_USERNAME_STEP) {
			registerAccountInfo[0] = ((EditText) findViewById(R.id.setupAccountUserNameValue))
					.getText().toString();
			registerAccountInfo[1] = ((EditText) findViewById(R.id.setupAccountEmailValue))
					.getText().toString();

			/** must encrypt passwords **/
			registerAccountInfo[2] = (((EditText) findViewById(R.id.setupAccountPasswordValue))
					.getText().toString());
			registerAccountInfo[3] = (((EditText) findViewById(R.id.setupAccountConfirmPasswordValue))
					.getText().toString());

		}

		else if (stepNumber == ADD_BANK_INFO_STEP) {

			bankInfo[0] = ((EditText) findViewById(R.id.bankValue)).getText()
					.toString();
			bankInfo[1] = ((EditText) findViewById(R.id.usernameValue))
					.getText().toString();
			bankInfo[2] = ((EditText) findViewById(R.id.passwordValue))
					.getText().toString();

		}

	}

	public void onAddExistingAccountInfo(JSONObject json) {
		String status = null;
		String message = null;

		try {
			status = json.getString("status");
		} catch (JSONException e) {
			e.printStackTrace();
		}

		try {
			message = json.getString("message");
		} catch (JSONException e1) {
			// e1.printStackTrace();
		}

		if (status.equals("success")) {

			this.dbHelper.setMode(DBHelper.EXISTING_ACCOUNT_MODE);
			Intent intent = new Intent(this, TabRoot.class);
			intent.putExtra("START_TAB", "view_savings");
			this.startActivity(intent);
		}

		if (message != null && message.equals("mfa")) {
			/** respond to MFA questions **/
			Intent intent = new Intent(this, MFAActivity.class);

			intent.putExtra("json", json.toString());
			this.startActivity(intent);

		}
	}

	// called after a login thread is executed
	public void onAuthenticate(String username, boolean result) {

		if (result == true) {
			this.dbHelper.setUsername(username);

			if (this.dbHelper.getMode() == DBHelper.CREATE_ACCOUNT_MODE)
				this.webHelper.getAccountInfo(false);
			else if (this.dbHelper.getMode() == DBHelper.CREATE_ACCOUNT_MODE)
				this.webHelper.getExistingAccountInfo(false);

			this.webHelper.getUserInfo();

			this.stepNumber++;
			this.changeToStepLayout();

		} else {
			this.webHelper.logout();
		}

	}

}
